package cn.nio.网络io;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * NIO服务端程序
 *
 * @author Mxb
 * @version 1.0
 * @date 2020/7/31 11:25
 */
public class NIOServer {
    public static void main(String[] args) throws IOException {
        // 1 得到一个ServerSocketChannel 对象 老大
        ServerSocketChannel channel = ServerSocketChannel.open();

        // 2 得到一个Selector 对象，间谍
        Selector selector = Selector.open();

        // 3 绑定一个端口号
        channel.bind(new InetSocketAddress(8888));

        // 4 设置非阻塞方式
        channel.configureBlocking(false);

        // 5 把 ServerSocketChannel对象注册给 Selector对象
        channel.register(selector, SelectionKey.OP_ACCEPT);

        // 6 干活
        while (true) {
            // 1 监控客户端，
            if (selector.select(2000) == 0) {
                System.out.println("服务端连接失败，执行其他任务中。。。");
                continue;
            }

            // 2 得到 ，判断通道里的事件
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();

                // 客户端连接事件
                if (key.isAcceptable()) {

                    System.out.println("OP_Accept");
                    SocketChannel socketChannel = channel.accept();
                    socketChannel.configureBlocking(false);
                    // 将网络通道注册给 选择器
                    socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                // 读取客户端数据事件
                if (key.isReadable()) {
                    SocketChannel readChannel = (SocketChannel) key.channel();
                    ByteBuffer attachment = (ByteBuffer) key.attachment();
                    readChannel.read(attachment);
                    System.out.println("客户端发来数据：" + new String(attachment.array()));
                }
                // 3 手动从集合中移除当前key,防止 重复处理
                iterator.remove();
            }
        }
    }
}
